\section{Présentation des \textit{shields} Arduino}

\subsection{\textit{Shield} XBee}
\subsubsection{Fonctionnement}

Le \textit{shield} Xbee permet à une carte Arduino de communiquer sans fil en utilisant la technologie Zigbee. Le module peut communiquer jusqu'à 30 mètres à l'intérieur et 90 mètres à l'extérieur (sur zone dégagée).
Il suffit, pour faire communiquer deux modules, d'écrire sur le port
série. La chaîne de caractère est alors directement broadcastée, et les
modules récepteurs affichent alors la chaîne reçue sur le port série.
\newline

\textbf{\normalsize{Formatage des données au sein du port série}}

Le port série autorise le formatage des données sur son flux d'écriture/lecture. Ainsi, il est possible d'écrire au format \texttt{byte} (format brut), \texttt{bin} (binaire), \texttt{oct} (octal), \texttt{hex} (hexadécimal), \texttt{dec} (décimal), ainsi que flottant.

Exemples :
\begin{itemize}
\item Serial.print(78, BYTE) donne "N"
\item Serial.print(78, BIN) donne "1001110"
\item Serial.print(78, OCT) donne "116"
\item Serial.print(78, DEC) donne "78"
\item Serial.print(78, HEX) donne "4E"
\item Serial.println(1.23456, 0) donne "1"
\item Serial.println(1.23456, 2) donne "1.23"
\item Serial.println(1.23456, 4) donne "1.2346"\\
\end{itemize}

Il faut donc connaître du côté réception le format des données pour éviter leur corruption.

\subsubsection{Exemple d'application - Clignotement de LED à distance}

Cet exemple présente le dialogue entre deux modules Xbee, l'un donnant l'ordre de faire clignoter une LED branchée sur l'autre module.

Le module récepteur a donc une LED de branchée sur un pin déclaré en \texttt{OUTPUT}. Il effectue une attente active en lecture sur le port série. Dès qu'un entier est lu (1 dans notre cas) il allume la LED, sinon il l'éteint.\\

\begin{figure}[!h]
\centering
\shadowbox{
\begin{lstlisting}[breaklines=true, breakatwhitespace=true]
int incomingByte = 0;
int led = 8; //Declare la led branchee sur la pin 8

void setup(){
  Serial.begin(9600); // Demarre le port serie a une vitesse de 9600 bps.
  pinMode(led, OUTPUT);
}

void loop(){
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
  }     
  if(incomingByte == '0'){
    digitalWrite(led, LOW);
  } 
  else if (incomingByte == '1'){ 
    digitalWrite(led, HIGH);
  }
}
\end{lstlisting}}
\includegraphics[angle=180,scale=80]{xbee.png}
\caption{Code \& branchement du récepteur}\label{fig:somefiglabel}
\end{figure}

Le module émetteur écrit simplement des suites de 0 et de 1 (selon une fréquence choisie) sur le port série. Le \textit{shield} Xbee se charge lui d'envoyer l'information sur les ondes.\\

\begin{figure}[!h]
\centering
\shadowbox{
\begin{lstlisting}
void setup(){
  Serial.begin(9600);
}

void loop(){
  Serial.print(1);
  delay(500);
  Serial.print(0);
  delay(1000);
}
\end{lstlisting}}
\caption{Code de l'émetteur}\label{fig:somefiglabel}
\end{figure}

\subsubsection{Problèmes rencontrés}
Nous avons eu beaucoup de problèmes pour réussir à envoyer du code sur la board lorsque le module Xbee était branché. En fait, nous nous sommes rendus compte qu'envoyer du code avec le module Xbee branché n'était pas possible, car le port série communiquait alors avec le chipset Xbee et non avec le chipset Arduino.

Ainsi, nous sommes obligés, à chaque envoi de code, de débrancher le module Xbee puis de le rebrancher une fois le code uploadé, et ce sur chaque mainboard. Cela est donc assez contraignant au niveau du temps et des manipulations à réaliser.

\subsection{\textit{Shield} Wi-Fi}

\subsubsection{Fonctionnement}

L'utilisation et la configuration du module Wi-Fi se fait par le port série grâce à des commandes du type \texttt{set wlan auth <value>}, \texttt{join <ssid>}, \texttt{open <addr> <port>} etc...

Cependant, une bibliothèque\cite{Wifly} expérimentale existe pour ce module, rendant la chose beaucoup plus simple. Nous y avons juste ajoutés une fonction \textit{enableDHCP()} qui active l'acquisition automatique d'adresses IP par le protocole DHCP. Il faut laisser au module le temps de se connecter au réseau, d'acquérir une IP, d'effectuer les requêtes etc... afin d'éviter tout problème de synchronisation entre le code et la carte Wi-Fi. Trois diodes sont présentes sur la carte Wi-Fi pour nous informer de l'état de la connexion, suivant le fonctionnement suivant\footnote{Tableau extrait du \textit{Reference Guide}\cite{ArdWifly}}:

\begin{center}
\begin{tabular}{|c|c|c|c|}
\hline
Condition & Red LED & Yellow LED & Green LED\\
\hline
\hline
On solid & Not associated & & Connected over TCP\\
\hline
Fast blink & & Rx/Tx data transfer & No IP address\\
\hline
Slow blink & Associated, No Internet, & & IP address OK\\
\hline
OFF & Associated, Internet OK & & \\
\hline
\end{tabular}
\end{center}

\subsubsection{Exemple d'application - Hébergement d'un serveur web}
Les modules Wi-Fi peuvent \emph{simuler} un serveur web en envoyant sur une socket (ouverte sur le port 80) des chaînes de caractères formatées en requêtes HTTP.
Le programme consiste alors en une simple acquisition d'adresse IP (en mode infrastructure sur cet exemple), une attente de connexion entrante sur la socket (port 80) et l'envoi d'une chaine HTTP répondant à un GET.

\shadowbox{
\begin{lstlisting}
#include "WiFly.h"

Server server(80);

void setup() {
  WiFly.begin();
  [...]
}

void loop() {
  Client client = server.available();
  if (client) {
  boolean current_line_is_blank = true;
  while (client.connected()) {
    if (client.available()) {
      char c = client.read();
      if (c == '\n' && current_line_is_blank) {
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/html");
        client.println();
        client.println("Hello world !");
        break;
      }
      if (c == '\n') {
        current_line_is_blank = true;
      } 
      else if (c != '\r') {
        current_line_is_blank = false;
      }
    }
  }
  delay(100);
  client.stop();
}
\end{lstlisting}}

La connexion s'effectue simplement en ouvrant un navigateur sur l'url $http:\backslash\backslash@IP\_MODULE$.

\subsubsection{Problèmes rencontrés}
\textbf{\normalsize{Utilisation d'un réseau en mode infrastructure}}

Le premier problème auquel nous nous sommes heurtés a été la non
possession d'un réseau Wi-Fi infrastructure pour pouvoir s'y connecter
et effectuer nos tests. En effet, les réseaux Wi-Fi disponibles sur le campus sont des réseaux avec des protocoles de connexion sécurisés, inutilisables avec nos modules Arduino.

Nous avons résolu le problème en utilisant un routeur propageant
un réseau Wi-Fi en mode infrastructure.
\newline

\textbf{\normalsize{\textit{Shield} d'origine inutilisable}}

En effet, lors de sa livraison, le \textit{shield} Wi-Fi n'était pas utilisable en l'état actuel puisqu'aucun moyen de brancher le \textit{shield} sur la carte Arduino n'existait. Nous avons donc soudé directement sur le \textit{shield} des broches pour pouvoir à la fois brancher le \textit{shield} sur la carte Arduino, et à la fois brancher d'autres entrées sur le \textit{shield} Wi-Fi.

\begin{figure}[!h]
\centering
\includegraphics[scale=0.45]{soudure-shield-wifi.jpg}
\caption{Résultat de la soudure du \textit{shield} Wi-Fi}\label{fig:somefiglabelx}
\end{figure}

\textbf{\normalsize{Extinction du \textit{shield} après un temps d'inactivité}}

Il se trouve qu'après un certain moment d'inactivité (environ 30 secondes), le module Wi-Fi n'est plus joignable (ni par socket ni par ping). Après de longues recherches pour résoudre le problème (notamment les temps d'inactivité par défaut), nous avons utilisés le programme \textit{HardwareFactoryReset} de la bibliothèque Wifly\cite{Wifly} citée plus haut, remettant les modules WiFly dans leurs paramètres d'usine. Ils marchent maintenant normalement, sans s'éteindre.
\newpage

\subsection{\textit{Shield} GPS}

\subsubsection{Fonctionnement}
Il existe une multitude de \textit{shield} GPS compatibles avec Arduino. Chacun a un mode de fonctionnement différent. Le \textit{shield} qui nous a été fourni est le DS-GPM.S. Ce module GPS possède une connexion de type ${I^2}C$ qui permet de communiquer avec seulement deux entrées analogiques (entrées 4 et 5), laissant ainsi le port série libre pour les autres modules (comme le GSM ou le Wi-Fi). La seule opération que l'on puisse faire sur le module GPS est la lecture des valeurs des différents registres (112 registres au total). \\

En outre, le module GPS possède 4 jumpers qui permettent de configurer l'adresse de lecture, ce qui fait qu'il est possible de brancher 4
modules en même temps qui utilisent tous la communication ${I^2}C$, et ceci en jouant sur la valeur de l'adresse de lecture.

\subsubsection{Exemple d'application - Affichage des coordonnées sur le port série}
 
Ce code lit les différentes valeurs de la latitude et longitude directement dans les registres du module GPS, puis écrit les coordonnées formatées sur le port série.
La fonction \texttt{GetSingle()} sert à retourner l'octet contenu à l'adresse \emph{Address}.
\newline

\shadowbox{
\begin{lstlisting}
#include <Wire.h>
#define GPM 0x68  	 

byte Address;
byte Data;
void setup()
{
  Wire.begin(); 
  Serial.begin(9600);
  get_infos();

}
void get_infos(){
  
  Serial.print("Latitude: ");
  Address = 14;                             
  Data = GetSingle();                                 
  Serial.print(Data, DEC);                            
  [...]
  Address = 32;        
  Data = GetSingle();  
  Serial.println(Data, BYTE);  
}
\end{lstlisting}}
\newpage

\subsubsection{Problèmes rencontrés}
Comme le \textit{shield} Wi-Fi, le \textit{shield} GPS nécessite des soudures pour être connecté à la carte Arduino.

\begin{figure}[!h]
\centering
\includegraphics[scale=0.45]{soudure-shield-gps.jpg}
\caption{Résultat de la soudure du \textit{shield} GPS}\label{fig:somefiglabelx}
\end{figure}

{Lorsque le module est déplacé sur une grande distance en étant éteint, son temps de synchronisation avec les satellites peut être relativement long (jusqu'à 30min). Une LED bleue sur le module indique l'état de synchronisation du GPS:\newline
\begin{itemize}
	\item Fixe : le module n'est pas synchronisé.
        \item Clignotement lent : le module est synchronisé et immobile.
	\item Clignotement rapide : le module est synchronisé et mobile.
\end{itemize}
Il est également possible de connaître l'état du module en lisant le quatrième et le cinquième bit du registre 112.}

\subsection{\textit{Shield} GSM/GPRS}

\subsubsection{Fonctionnement}

Le dialogue avec le module GSM via le terminal du port série n'a posé aucun problème, et nous avons pu \textit{communiquer} avec le module sans souci particulier.

En effet, comme le module Xbee, les fonctionnalités du module GSM sont accessibles via le port série grâce à des commandes \texttt{AT}.\\

Principales commandes que nous avons utilisé sur le module GSM :\\
\begin{center}
\begin{tabular}{|c|c|}
\hline
Commandes & Description\\
\hline
AT & \'Etat de la connexion au port série\\
AT+CPIN="****" & Débloquage du PIN\\
AT+COPS? & Retourne le nom du réseau du mobile\\
ATD**********; & Effectue un appel vocal\\
ATH & Termine un appel en cours\\
AT+CSCA? & Récupère le numéro du centre d'appel SMS\\
AT+CMGF=1 & Sélectionne le format pour les SMS (1 pour format texte)\\
AT+CMGS="**********" & Spécifie le numéro du destinataire pour les SMS\\
AT+CNMI=2,2,0,0 & Permet la redirection de flux vers le port série\\
\hline
\end{tabular}
\end{center}

\begin{figure}[!h]
\centering
\includegraphics[scale=0.17]{shield_gsm.jpg}
\caption{\textit{Shield} GSM}\label{fig:somefiglabelx}
\end{figure}

\subsubsection{Exemple d'application - Envoi de SMS}

\shadowbox{
\begin{lstlisting}
int led = 13;
int onModulePin = 2;            // le PIN permettant d'allumer le module

void switchModule(){
  digitalWrite(onModulePin,HIGH);
  delay(2000);                  //Reboot du module
  digitalWrite(onModulePin,LOW);
}

void setup(){
  pinMode(led, OUTPUT);
  pinMode(onModulePin, OUTPUT);

  Serial.begin(19200);          // specifie la vitesse de transmission

  switchModule();               // allume le module
  
 delay(5000);                   // attente de l'etablissement de la connexion
 

 Serial.println("AT+CMGF=1");   // selectionner le format texte pour
                                   les SMS
}

void loop(){  
  Serial.print("AT+CMGS=");     // specifie le numero du destinataire
  Serial.print(34,BYTE);        // envoie du caractere "
  Serial.print("06********");     
  Serial.println(34,BYTE);
  Serial.print("Hello World."); // Texte a envoyer
  Serial.print(0x1A,BYTE);      // envoie du caractere hexa 1A qui marque
                                   la fin du message
  Serial.print("AT*PSCPOF");    // eteint le module GSM

}
\end{lstlisting}}
\newpage

\subsubsection{Problèmes rencontrés}

\begin{itemize}
\item {Le premier problème rencontré était l'absence de l'antenne GSM qui empêchait toute opération d'envoi et de réception d'appel ou de SMS (message d'erreur \textit{''NO CARRIER''}).

\begin{figure}[!h]
\centering
\includegraphics[scale=0.13]{shield_gsm2.jpg}
\caption{\textit{Shield} GSM - Branchement de l'adaptateur de l'antenne}\label{fig:somefiglabelx}
\end{figure}}

\item{Une mauvaise configuration du taux de transmission engendrait un comportement du \textit{shield} imprévisible et aléatoire. Un réglage à 19200 bps a permis de résoudre le problème.}
\item{Au départ, des pertes de connexions récurrentes apparaissaient, or il est indiqué dans les spécifications du \textit{shield} GSM qu'une simple alimentation par le port USB peut ne pas être suffisante pour alimenter le \textit{shield} et ainsi empêcher d'obtenir une connexion stable. L'utilisation d'une alimentation externe (9V) a corrigé ce problème.}
\item{Entre les différentes commandes envoyées au \textit{shield}, il est parfois nécessaire d'utiliser des \textit{delay()} pour permettre au \textit{shield} d'avoir le temps de bien interpréter chaque commande.}
\item{Un des plus gros problème rencontré a été le caractère hexadécimal de fin de message \texttt{0x1A} lors de l'envoi d'un SMS qui n'était pas interprété par l'environnement de développement Arduino. L'utilisation du logiciel \textit{X-ctu} permettant l'interprétation de tels caractères a corrigé partiellement ce problème. Nous nous sommes finalement rendu compte que c'est la position des jumpers qui posait problème. Ils doivent être positionnés sur \textit{Arduino} pour que cela fonctionne.}
\end{itemize}

\begin{figure}[!h]
\centering
\includegraphics[scale=0.85]{schema_gsm.jpg}
\caption{Emplacement des jumpers sur la carte GSM\cite{Libe}}\label{fig:somefiglabelx}
\end{figure}
